package navigator
{

import summit.basecamp.constants.BasecampResource;
import summit.basecamp.wrappers.AbstractWrapper;
import summit.basecamp.wrappers.CommentWrapper;
import summit.basecamp.wrappers.IStandardWrapper;
import summit.events.BasecampAPIEvent;
	
/** Event handlers for the OK response of various Basecamp API calls. **/
public class BasecampAPIEventHandlers
{

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// OK handlers for API Calls initialized from the resource tree

/**
 * @private
 * 
 * Called when Summit processes the successful Basecamp API response from
 * our request to get a list of projects.
 */
public static function handleProjectWrapperOKEvent(e:BasecampAPIEvent):void
{
	// Need to walk through each project included in the returned XML
	// XML Format looks like: <projects><project/> ... <project/></projects>
	
	for each(var element:XML in e.data.project)
	{
		// For each project - make a simple entry in the tree
		var entry:XML = new XML(Constants.PROJ_ENTRY_XML);
		entry.@name 		= element.name;
		entry.@status 		= element.status;
		entry.@id 			= element.id; 
		entry.@apiType 		= element.localName();
		entry.@projectId 	= element.id;
		
		State.tree.treeXML.child(element.status)[0].appendChild(entry);
		
		// once the node is added to the tree - add the project to the list
		// of artifacts. this allows us to retrieve the project by id - and
		// display it's properties in the propertyviewer
		State.resources[element.id] = element;
	}
	
	// now that we're good - we'll expand so the user has something to look
	// at
	Helpers.expandTree();
}


/** @private Event handler for OK event on successful list call. **/
public static function handleListOKEvent(e:BasecampAPIEvent):void
{
	Helpers.processAPIResult(e.data); // add data to the tree
}	

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// OK handlers for API Calls initialized from the properties viewer

/** @private Called on successful delete. **/
public static function handleDestroyOKEvent(e:BasecampAPIEvent):void
{
	// need to remove the currently selected node from the artifacts
	// bucket
	delete State.resources[(State.tree.selectedItem as XML).@id.toString()];
	
	var oldNode:XML = State.tree.selectedItem as XML;
	State.tree.selectedItem = oldNode.parent();		// move the selection up 
	
	// remove the node from the tree
	delete (State.tree.selectedItem as XML).children()[oldNode.childIndex()];
	
	State.tree.handleTreeClickEvent(); // simulate a click	
}

/** @private Called on successful create **/
public static function handleCreateOKEvent(e:BasecampAPIEvent):void
{
	// Once a create is successful, we need to 'read' the new item... 
	// an exception - milestones - because the new item
	// comes down with the 'ok' event
	
	// Basecamp provides the id of the new item in the response headers
	// which Summit exposes to us (again, not for milestones).
	
	var field:String = e.responseHeaders.Location;
	
	// From here - we need the id - so we can do a 'read' 
	var regExp:RegExp = new RegExp("[0-9].*[0-9]"); // RegEx to pull id
	var id:String = regExp.exec(field);				
	
	State.editData = new Object();
	State.editData.newItem = true;
	
	if(e.loader.basecampRequest.resource == BasecampResource.MILESTONE)
	{
		// On create - Basecamp's response includes the data of the 
		// new Milestone
		State.tree.finishRead(null, e.data);
	}
	else
	{
		var node:XML = (State.tree.selectedItem as XML);
		
		var abstractWrapper:AbstractWrapper;
		
		// Special case - if a todo-list (not the folder) is selected
		// and create is click - we need to handle the call as TodoItem
		// resource.
		if(node.@resource == "TodoList" && node.@id != -2) 
			abstractWrapper = Helpers.getClass("TodoItem");
		else abstractWrapper = Helpers.getClass(node.@resource);
		
		var stdWrapper:IStandardWrapper = abstractWrapper as IStandardWrapper;
		Helpers.registerCommonEvents(stdWrapper.loader);
		
		stdWrapper.loader.addEventListener(BasecampAPIEvent.OK, 
		handleReadOKEvent);
		
		stdWrapper.read(id, node.parent().@projectId); 
	}
}

/** @private Called on successful prepare **/
public static function handlePrepareOKEvent(e:BasecampAPIEvent):void
{
	// In the case of 'milestones' - we need a little data help - 
	// The milestone guy is wrapped in a 'request' because of additional
	// flags that can optionally be uploaded with the milestone. 
	// We need to strip that off for our usage in nav
	if(e.resource == BasecampResource.MILESTONE) 
		e.data = new XML(e.data.milestone);
	
	// Display the returned data in edit mode... So the user can fill
	// out the information and create teh resoruce. 
	Helpers.enterEditMode(e.data, false);	
}

/** @private Called on successful read **/
public static function handleReadOKEvent(e:BasecampAPIEvent):void
{
	var items:XML;
	var list:XML;
	var mod:String = e.loader.basecampRequest.resource;
	
	if(e.loader.basecampRequest.resource == BasecampResource.TODOLIST)
	{
		items = new XML(e.data.child("todo-items")[0]);
		delete e.data.child("todo-items")[0];
		list = new XML("<todo-lists/>");	
	}
	else 
	{
		var len:int = mod.length - 1;
		
		mod = mod.charAt(len) == "y" ? mod.substr(0, len) + "ies" : mod + "s";
		
		list = new XML("<" + mod + "/>");
	}
	
	State.tree.finishRead(list, e.data, items);
}

/** @private Called on successful edit **/ 
public static function handleEditOKEvent(e:BasecampAPIEvent):void
{
	Helpers.enterEditMode(e.data);	
}


/** @private Called on successful Update **/
public static function handleUpdateOKEvent(e:BasecampAPIEvent):void
{
	// At this point: The user selected an item - clicked 'edit' - then
	// edited the item - next clicked 'submit edit' - and now the server
	// is responding to tell us the edit is complete.
	
	var field:String = e.loader.statusEvent.responseURL;
	
	// From here - we need the id - so we can do a 'read' 
	var regExp:RegExp = new RegExp("[0-9].*[0-9]"); // RegEx to pull id
	var id:String = regExp.exec(field);			
	
	delete State.resources[id];
	
	var oldNode:XML = State.tree.selectedItem as XML;
	State.tree.selectedItem = oldNode.parent();		// Move tree selection
	State.editData = new Object();
	State.editData.oldIndex = oldNode.childIndex();	// index under parent of
													// the original item
	
	// delete item out of the tree
	delete (State.tree.selectedItem as XML).children()[oldNode.childIndex()];
	
	var abstractWrapper:AbstractWrapper = Helpers.getClass(
	oldNode.@resource);
	
	Helpers.registerCommonEvents(abstractWrapper.loader);
	
	abstractWrapper.loader.addEventListener(BasecampAPIEvent.OK, 
	BasecampAPIEventHandlers.handleReadOKEvent);
	
	var stdWrapper:IStandardWrapper = abstractWrapper as IStandardWrapper;
	
	if(stdWrapper) stdWrapper.read(id, State.tree.selectedItem.@projectId);
	else (abstractWrapper as CommentWrapper).read(id);
}
}
}